package local.blueheart.data.springdatademo.service.impl;

import local.blueheart.data.springdatademo.domain.archive.ArchiveIndexData;
import local.blueheart.data.springdatademo.domain.archive.DocCompositedId;
import local.blueheart.data.springdatademo.domain.config.ApplicationDO;
import local.blueheart.data.springdatademo.domino.*;
import local.blueheart.data.springdatademo.exception.DominoException;
import local.blueheart.data.springdatademo.exception.DominoExcpetionHandler;
import local.blueheart.data.springdatademo.repository.archive.ArchiveIndexRepository;
import local.blueheart.data.springdatademo.service.ArchiveIndexDataService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;

@Service("archiveIndexDataService")
@Scope("prototype")
public class ArchiveIndexDataServiceImpl implements ArchiveIndexDataService {

    private static final Logger LOGGER = LoggerFactory.getLogger(ArchiveIndexDataServiceImpl.class);

    @Autowired
    private ArchiveIndexRepository archiveIndexRepository;

    private ApplicationDO applicationDO;
    //默认启动
    private AtomicBoolean atomicBoolean = new AtomicBoolean(true);


    public ArchiveIndexDataServiceImpl() {
    }

    public ArchiveIndexDataServiceImpl(ApplicationDO applicationDO) {
        this.applicationDO = applicationDO;
    }

    public ApplicationDO getApplicationDO() {
        return applicationDO;
    }

    public void setApplicationDO(ApplicationDO applicationDO) {
        this.applicationDO = applicationDO;
    }

    @Override
    public void collectArchiveIndexData() {
        DSession dSession = null;
        DDatabase dDatabase = null;
        DView dView = null;
        DDocument dDocument = null;
        DDocument tempDocument = null;
        while (atomicBoolean.get()==true) {
            try {
                dSession = DSession.sessionFactory(applicationDO.getAddress(), applicationDO.getUserName(), applicationDO.getPassWord());
                LOGGER.info("创建Session: server##{}##user##{}##password##{}",applicationDO.getAddress(),applicationDO.getUserName(),applicationDO.getPassWord());
                dDatabase = dSession.getDatabase("", applicationDO.getIndexPath());
                LOGGER.info("连接数据库: db##{}",applicationDO.getIndexPath());
                String viewName = applicationDO.getModuleDO().getSearch().split("\\+")[1];
                dView = dDatabase.getView(viewName);
                LOGGER.info("获得视图: view##{}",viewName);
                dDocument = dView.getDocument(dDocument);
                while (!dDocument.isNull() && atomicBoolean.get() == true) {
                    DocCompositedId docCompositedId = DDocumentHelper.getArchiveIndexId(dDocument);
                    Optional<ArchiveIndexData> tData = archiveIndexRepository.findById(docCompositedId);
                    if (tData.isPresent()) {
                        tempDocument = dDocument;
                        LOGGER.info("文档已经存在 {}",docCompositedId);
                        dDocument = dView.getDocument(tempDocument);
                        tempDocument.recycle();
                        if(dDocument.isNull()){
                            //退出整个线程
                            atomicBoolean.set(false);
                            break;
                        }
                        LOGGER.info("document = {},atomicBoolean = {}",dDocument.isNull(),atomicBoolean.get());
                        continue;
                    }
                    LOGGER.info("Doc文档: {}",docCompositedId);
                    ArchiveIndexData archiveIndexData = DDocumentHelper.getArchiveIndexData(dDocument);
                    archiveIndexData.setDocUniversalId(docCompositedId.getDocUniversalId());
                    archiveIndexData.setDbPath(docCompositedId.getDbPath());
                    archiveIndexData.setApplicationDO(applicationDO);
                    archiveIndexData.setModuleDO(applicationDO.getModuleDO());
                    LOGGER.info("数据库文档: {}",archiveIndexData);
                    archiveIndexRepository.save(archiveIndexData);
                    DDocumentHelper.updateDDocumentStatus(dDocument, applicationDO.getFlagField(), "YES");
                    LOGGER.info("更新Doc文档: {}",docCompositedId);
                    //archiveDataRepository.save(archiveData);
                    tempDocument = dDocument;
                    dDocument = dView.getDocument(tempDocument);
                    tempDocument.recycle();
                    LOGGER.info("document Null is = {},atomicBoolean = {}",dDocument.isNull(),atomicBoolean.get());
                    if(dDocument.isNull()){
                        //退出整个线程
                        atomicBoolean.set(false);
                        break;
                    }
                }

            } catch (DominoException e) {
                LOGGER.error("收集索引出错", e);
                DominoExcpetionHandler.handler(e);
                switch (e.getDominoExceptionEnum()){
                    case GET_DOC_ERR:
                        atomicBoolean.set(false);
                        break;
                        default:
                            try {
                                Thread.sleep(20);
                            } catch (InterruptedException e1) {
                                e1.printStackTrace();
                            }

                }
            } finally {
                if (dDocument != null) {
                    dDocument.recycle();
                }
                if (dView != null) {
                    dView.recycle();
                }
                if (dDatabase != null) {
                    dDatabase.recycle();
                }
                if (dSession != null) {
                    dSession.recycle();
                }
                LOGGER.info("关闭所有对象的IIOP");
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }




    public synchronized void startArchive() {
        atomicBoolean.set(true);
        collectArchiveIndexData();
    }

    public synchronized void stopArchive() {
        atomicBoolean.set(false);
    }

    @Override
    public void run() {
        startArchive();
    }
}
